/*
 * Copyright (c) 2013 Andaily Information Technology Co. Ltd
 * www.andaily.com
 * All rights reserved.
 *
 * This software is the confidential and proprietary information of
 * Andaily Information Technology Co. Ltd ("Confidential Information").
 * You shall not disclose such Confidential Information and shall use
 * it only in accordance with the terms of the license agreement you
 * entered into with Andaily Information Technology Co. Ltd.
 */
package cn.com.doone.common.uc.service;

import java.security.NoSuchAlgorithmException;
import java.util.List;
import java.util.Map;
import java.util.Set;

import javax.servlet.http.HttpServletRequest;

import org.apache.oltu.oauth2.common.exception.OAuthSystemException;

import cn.com.doone.common.uc.domain.oauth.AccessToken;
import cn.com.doone.common.uc.domain.oauth.ClientDetails;
import cn.com.doone.common.uc.domain.oauth.OauthCode;
import cn.com.doone.common.uc.service.dto.IpBlackList;
import cn.com.doone.common.uc.service.dto.LoginLog;

/**
 * 15-6-10
 *
 * @author Shengzhao Li
 */
public interface OauthService {

    ClientDetails loadClientDetails(String clientId);

    OauthCode saveAuthorizationCode(String authCode, ClientDetails clientDetails);

    String retrieveAuthCode(ClientDetails clientDetails) throws OAuthSystemException;
    
    /**
     * 根据username和clientid生成code
     * @param params
     * @return
     * @throws OAuthSystemException 
     */
    public String retrieveAuthCode(Map<String,Object> params) throws OAuthSystemException;
    
    public void removeAuthCode(String clientId,String username);

    AccessToken retrieveAccessToken(ClientDetails clientDetails, Set<String> scopes) throws OAuthSystemException;

    AccessToken retrieveAccessToken(ClientDetails clientDetails, Set<String> scopes, boolean includeRefreshToken) throws OAuthSystemException;

    //Always return new AccessToken, exclude refreshToken
    AccessToken retrieveNewAccessToken(ClientDetails clientDetails, Set<String> scopes) throws OAuthSystemException;

    OauthCode loadOauthCode(String code, ClientDetails clientDetails);

    boolean removeOauthCode(String code, ClientDetails clientDetails);

    // 根据code取username
    
    AccessToken retrieveNewAccessToken(ClientDetails clientDetails, String code) throws OAuthSystemException;
    //Always return new AccessToken
    AccessToken retrieveNewAccessToken(ClientDetails clientDetails) throws OAuthSystemException;
    
    public AccessToken retrieveNewAccessTokenByUsername(ClientDetails clientDetails, String username) throws OAuthSystemException;

    //grant_type=password AccessToken
    AccessToken retrievePasswordAccessToken(ClientDetails clientDetails, Set<String> scopes, String username) throws OAuthSystemException;

    //grant_type=client_credentials
    AccessToken retrieveClientCredentialsAccessToken(ClientDetails clientDetails, Set<String> scopes) throws OAuthSystemException;

    AccessToken loadAccessTokenByRefreshToken(String refreshToken, String clientId);

    AccessToken changeAccessTokenByRefreshToken(String refreshToken, String clientId) throws OAuthSystemException;
    
    AccessToken loadAccessToken(String clientId, String username, Set<String> scopes);
    
    /**
     * 根据应用标识获取应用信息
     * 
     * @author whm
     * @param appCode
     * @return
     */
    Map<String, Object> findAppInfo(String appCode);
    
    /**
     * 根据用户账号获取用户信息
     * 
     * @author whm
     * @param userAccount
     * @return
     */
    Map<String, Object> findUserInfoByUserAccount(String userAccount);
    
    /**
	 * 根据用户组id,应用id获取组授权应用数据
	 * 
	 * @author whm
	 * @param userGroupId
	 * @param appInfoId
	 * @return
	 */
	Map<String, Object> findUserGroupAppAuthorize(int userGroupId, int appInfoId);
	
	/**
	 * 根据用户id,应用id验证所属用户组是否授权应用
	 * 
	 * @author whm
	 * @param userId
	 * @return true-授权 false-未授权
	 */
	boolean valiUserGroupAndAppAuthorize(int userId, int appInfoId);
	
	/**
	 * 根据用户id,应用id验证用户是否授权应用
	 * 
	 * @param userId
	 * @param appInfoId
	 * @return true-授权 false-未授权
	 */
	boolean valiUserAndAppAuthorize(int userId, int appInfoId);
	
	/**
	 * 验证传入IP是否存在于IP黑名单中(在失效时间以内)
	 * 
	 * @author whm
	 * @param ip
	 * @return true-是 false-否
	 */
	boolean valiIPBlackList(String ip);
	
	/**
	 * 保存ip至黑名单
	 * 
	 * @author whm
	 * @param ip			IP
	 * @param invalidTime 	失效时间
	 * @param remarks		备注
	 */
	void saveIPBlackListInfo(IpBlackList IpBlackList);
	
	/**
	 * 删除ip黑名单数据
	 * 
	 * @author whm
	 * @param ip
	 */
	void deleteIPBlackListInfo(String ip);
	
	/**
	 * 根据IP更新ip黑名单数据
	 * 
	 * @author whm
	 * @param ip			
	 * @param invalidTime	失效时间
	 * @param remarks		备注
	 */
	void updateIPBlackListInfoByIP(String ip, String invalidTime, String remarks);
	
	/**
	 * 根据ID更新ip黑名单数据
	 * 
	 * @author whm
	 * @param id
	 * @param ip
	 * @param invalidTime	失效时间
	 * @param remarks		备注
	 */
	void updateIPBlackListInfoByID(int id, String ip, String invalidTime, String remarks);
	
	/**
	 * 验证IP是否存在于黑名单(where条件只有ip)
	 * 
	 * @author whm
	 * @param ip
	 * @return true-存在 false-不存在
	 */
	boolean valiIPExitBlackList(String ip);
	
	/**
	 * 验证ip是否存在白名单
	 * 
	 * @author whm
	 * @param ip
	 * @return true-存在 false-不存在
	 */
	boolean valiIPWhiteList(String ip);
	
	/**
	 * 查询ip黑名单数据
	 * 
	 * @author whm
	 * @param ip
	 * @param createTimeStart
	 * @param createTimeEnd
	 * @param invalidTimeStart
	 * @param invalidTimeEnd
	 * @return
	 */
	List<Map<String, Object>> findIPBlackList(String ip, String createTimeStart, String createTimeEnd, String invalidTimeStart, String invalidTimeEnd);
	
	/**
	 * 查询ip白名单数据
	 * 
	 * @author whm
	 * @param ip
	 * @param createTimeStart
	 * @param createTimeEnd
	 * @param invalidTimeStart
	 * @param invalidTimeEnd
	 * @return
	 */
	List<Map<String, Object>> findIPWhiteList(String ip, String createTimeStart, String createTimeEnd, String invalidTimeStart, String invalidTimeEnd);
	
	/**
	 * 保存用户授权应用信息
	 * 
	 * @author whm
	 * @param userId
	 * @param appinfoId
	 */
	void saveUserAppAuthorize(int userId, int appInfoId);
	
	boolean validWeakPassword(String password);
	
	/**
	 * 旧密码是否正确
	 * 
	 * @param password
	 * @return
	 */
	public boolean validCorrectPassword(String userAccount, String password, HttpServletRequest request) throws NoSuchAlgorithmException;
	
	/**
	 * 通过userInfoId判断密码是否正确
	 * @param userInfoId
	 * @param password
	 * @param request
	 * @return
	 * @throws Exception
	 */
	public boolean validCorrectPasswordByUserInfoId(String userInfoId,String password,HttpServletRequest request) throws Exception;
	
	/**
	 * 
	 * 通过账号修改密码
	 * @param userAccount
	 * @param password
	 * @return
	 */
	public void changePassword(String userAccount, String password,String p_code);
	
	/**
	 * 通过userInfoId修改密码
	 * @param userInfoId
	 * @param password
	 * @param p_code
	 */
	public void changePasswordByUserInfoId(String userInfoId,String password,String p_code);
	
	/**
	 * 保存登录日志
	 * 
	 * @param loginLog
	 */
	public void saveLoginLog(LoginLog loginLog);
	
	public int findUserInfoIdByAccount(String userAccount);
	
	/**
	 * 根据userId查看用户
	 * 
	 * @param userAccount
	 * @return
	 */
	public Map<String, Object> findUserInfoByUserId(String userInfoId);
	
	/**
	 * 查看某IP某时间段内，登录失败的次数
	 * 
	 * @param ip
	 * @param startTime
	 * @param endTime
	 * @return
	 */
	public int countLoginLogByIp(String ip, String startTime, String endTime);
	
	/**
	 * 统计某个时间段某账号登录失败的次数
	 * 
	 * @param userAccount
	 * @param startTime
	 * @param endTime
	 * @return
	 */
	public int countLoginLogByUserId(int userInfoId, String startTime, String endTime);
	
	/**
	 * 更新账号的锁定状态
	 * 
	 * @param userMap
	 */
	public void updateUserLock(Map<String, Object> userMap);
	
	/**
	 * 验证账号是否被锁定
	 * 
	 * @param resultMap
	 */
	public void validAccountLock(Map<String, Object> resultMap);
	
	/**
	 * 通过userId验证账号是否被锁定
	 * @param userId
	 */
	public void validAccountLockByUserId(Map<String,Object> resultMap);
	
	public void validIpLock(Map<String, Object> resultMap);
	
	/**
	 * 根据第三方账号获取用户信息
	 * 
	 * @param appCode
	 * @param appAccount
	 * @return
	 */
	public Map<String, Object> findUserInfoByAppAccount(String appCode, String appAccount);
	
	public Map<String, Object> findWedoStaffIdByAccount(String appCode, String userAccount);
	
	/**
	 * 账号绑定
	 * 
	 * @param request
	 */
	public boolean bindAuthAccount(HttpServletRequest request, String appCode) throws NoSuchAlgorithmException;
	
	/**
	 * 根据微信ID获取应用信息
	 * 
	 * @param appid
	 * @return
	 */
	public Map<String, Object> findAppInfoByWeChatId(String clientId, String appid);
	
	/**
	 * 根据token获取信息
	 * @param token
	 * @return
	 */
	public Map<String,Object> queryInfoByToken(String token);
	
	
}
